package com.pig4cloud.pigx.common.core.util.wechat;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.Random;

@Slf4j
@Component
@RequiredArgsConstructor
public class WechatGzhAuth {

	/**
	 * 调用微信公众号的接口 获取Access token 必输的一个请求参数 该值是固定的
	 */
	private final static String GRANT_TYPE = "client_credential";

	/**
	 * 调用微信公众号的接口 获取jsapi_ticket 必输的一个请求参数 该值是固定的
	 */
	private final static String GET_JSAPI_TICKET_TYPE = "jsapi";

	private static String[] strs = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
			"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I",
			"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

	private final static String APPID = "wx0e571bcbc93a89ac";

	private final static String SECRET = "b4508ae002e86cb9d254ebdc131de00c";

	private static RedisTemplate<String, String> redisTemplate;

	// private final static String URL = "https://m.mnyourui.com";

	public static void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
		WechatGzhAuth.redisTemplate = redisTemplate;
	}

	public static R getWeChatSignature(WeChatSignatureReqDTO weChatSignatureReqDTO) {
		// 调用微信公众号的接口 获取Access token
		String jsapiTicket = "";
		Object wechatTicket = redisTemplate.opsForValue().get("ggz_wechat_ticket");
		if (wechatTicket == null) {
			log.info("缓存不存在ticket");
			String accessToken = getAccessToken();
			if (StringUtils.isEmpty(accessToken)) {
				log.error("调用微信公众号的接口 未获取Access token");
				return R.failed("调用微信公众号的接口 未获取Access token");
			}

			// 调用微信公众号的接口 获取jsapi_ticket
			jsapiTicket = getJsapiTicket(accessToken);
			if (StringUtils.isEmpty(accessToken)) {
				log.error("调用微信公众号的接口 未获取jsapi_ticket");
				return R.failed("调用微信公众号的接口 未获取jsapi_ticket");
			}
		}
		else {
			log.info("缓存存在ticket, 从缓存中获取");
			jsapiTicket = wechatTicket.toString();
		}

		// 签名加密算法
		WeChatSignatureRespVO resp = getSignature(jsapiTicket, weChatSignatureReqDTO.getUrl());
		resp.setAppId(APPID);
		return R.ok(resp);
	}

	/**
	 * 获取accessToken
	 * @return
	 */
	public static String getAccessToken() {
		String accessTokenResp = HttpUtil
				.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret="
						+ SECRET + "");
		log.info("调用微信的接口 获取AccessToken，响应数据为:\n{}", accessTokenResp);
		return JSON.parseObject(accessTokenResp).getString("access_token");
	}

	/**
	 * 获取ticket
	 * @param accessToken
	 * @return
	 */
	public static String getJsapiTicket(String accessToken) {
		String jsapiTicketResp = HttpUtil
				.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi");
		log.info("调用微信的接口 获取jsapi_ticket，响应数据为:\n{}", jsapiTicketResp);
		String ticket = JSON.parseObject(jsapiTicketResp).getString("ticket");
		redisTemplate.opsForValue().set("ggz_wechat_ticket", ticket, Duration.ofSeconds(7000));
		log.info("写入缓存ticket");
		return ticket;
	}

	public static WeChatSignatureRespVO getSignature(String jsapiTicket, String url) {
		WeChatSignatureRespVO resp = new WeChatSignatureRespVO();
		// 生成随机字符串
		String nonceStr = createNonceStr();
		// 时间戳
		long timestamp = System.currentTimeMillis();
		// 通过jsapi_ticket、随机字符串、时间戳
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("jsapi_ticket=").append(jsapiTicket).append("&").append("noncestr=").append(nonceStr)
				.append("&").append("timestamp=").append(timestamp).append("&").append("url=")
				.append(url.indexOf("#") >= 0 ? url.substring(0, url.indexOf("#")) : url);
		String signatureStr = stringBuilder.toString();
		log.info("微信签名 she1加密前的数据：{}", signatureStr);
		String signature = DigestUtils.sha1Hex(signatureStr);
		log.info("微信签名，she1加密后的数据：{}", signature);

		// 返回数据
		resp.setNonceStr(nonceStr);
		resp.setTimestamp(String.valueOf(timestamp));
		resp.setSignature(signature);
		return resp;
	}

	/**
	 * 返回15位的随机数
	 * @return
	 */
	public static String createNonceStr() {
		Random r = new Random();
		StringBuilder sb = new StringBuilder();
		int length = strs.length;
		for (int i = 0; i < 15; i++) {
			sb.append(strs[r.nextInt(length - 1)]);
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		// WeChatTencentBizSvcImpl a = new WeChatTencentBizSvcImpl();
		// a.getWeChatSignature();
	}

}
